package com.qf.security;

/*
 *  @author Administrator
 *  @version V1.0
 *  @Project banwoqiche
 *  @Package com.qf.security
 *  @Description
 *  @Date2022/3/29 0029 15:40
 */

import com.qf.mapper.UserMapper;
import com.qf.security.handler.MyFailHandler;
import com.qf.security.handler.MySuccessHandler;
import com.qf.security.service.MyUserSetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;

@Component
@EnableWebSecurity//开启spring security
@EnableGlobalMethodSecurity(prePostEnabled = true,jsr250Enabled = true,proxyTargetClass = true)//开启注解进行权限判断
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    private UserMapper userMapper;
    private MyUserSetailService userSetailService;
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    private MySuccessHandler mySuccessHandler;
    private MyFailHandler myFailHandler;
    @Autowired
    public void setMyFailHandler(MyFailHandler myFailHandler) {
        this.myFailHandler = myFailHandler;
    }
    @Autowired
    public void setMySuccessHandler(MySuccessHandler mySuccessHandler) {
        this.mySuccessHandler = mySuccessHandler;
    }

    @Autowired
    public UserMapper getUserMapper() {
        return userMapper;
    }

    @Autowired
    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }
    @Autowired
    public void setUserSetailService(MyUserSetailService userSetailService) {
        this.userSetailService = userSetailService;
    }

    @Autowired
    public void setbCryptPasswordEncoder(BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

    //告诉security 我当前登录的账号在数据库中密码以及编码格式,剩下的就是spring security进行操作
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userSetailService)//我们就知道了数据库中的密码
                .passwordEncoder(bCryptPasswordEncoder);//密码可能是MD5 需要转换等等,我们指定一个密码的转换方式
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        //以下地址会被排除在spring security之外, 大部分情况下和下面permitAll效果一下,这个是直接不走security
        web.ignoring().antMatchers("/js/**", "/css/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //告诉security 我们页面传递过滤的数据中哪个是用户名,哪个是密码
        http.csrf().disable();
        http.authorizeRequests()//认证请求
                .and().formLogin()//sprringsecurity给我们提供了一个默认的登录页面,默认地址就是/login, 我们可以改
                //.disable()//禁用默认的登录方式
                //.loginPage("/login.html")//自己定义的默认登录界面,也可以不写,spring会有一个
                .loginProcessingUrl("/login")//自定义我们的登录处理地址,注意这个地址不需要我们写controller,
        // 我们只需要写路径就行, security会自动帮我们处理这个地址,所以这个地址不要和项目的地址重复
           //     .usernameParameter("uName")//自定义用户名的参数,默认是username,如果是用的默认页面,可以忽略,写了也白写
                //.passwordParameter("pwd")//自定义密码的参数名
                .successHandler(mySuccessHandler)//自定义成功之后怎么办?//我们有两个事情要做, 第一个成功之后返回什么? 第二个登录成功之后查询用户的权限
    //            .failureHandler(myFailHandler)//登录失败之后怎么做
                .permitAll()//放行,登录地址是不需要拦截的,所谓的放行是先到security然后发现不需要拦截,就放行
                .and().logout()
                .logoutUrl("/logout").permitAll()//自定义退出的地址,这个地址也不需要你写,security会自动退出并清理登录数据
                .and().authorizeRequests().anyRequest()//任意地址,除了上面单独配置的其它地址
                .authenticated();//必须登录才可以访问,是否需要登录取决于业务


    }
}
